﻿namespace LaoLuo
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// provides static methods to throw exceptions
    /// </summary>
    public static class ThrowHelper
    {
        /// <summary>
        /// Throws a <see cref="TypeArgumentException"/> if <typeparamref name="T"/> is not a numeric type
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public static void ThrowIfNotNumericType<T>()
            where T : struct
        {
            if (!typeof(T).IsNumeric())
            {
                throw new TypeArgumentException("must be numeric");
            }
        }

        /// <summary>
        /// Throws a <see cref="TypeArgumentException"/> if <typeparamref name="T"/> is not an enum
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public static void ThrowIfNotEnumType<T>()
            where T : struct, IComparable, IFormattable, IConvertible
        {
            if (!typeof(T).IsEnum)
            {
                throw new TypeArgumentException(typeof(Enum));
            }
        }

        /// <summary>
        /// Throws a <see cref="TypeArgumentException"/> if <typeparamref name="T"/> is not a flags enum
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public static void ThrowIfNotFlags<T>() where T : struct, IComparable, IFormattable, IConvertible
        {
            ThrowIfNotEnumType<T>();

            if (!EnumInternals<T>.IsFlags)
            {
                throw new TypeArgumentException("Can't call this method for a non-flags enum");
            }
        }

        /// <summary>
        /// Throws an <see cref="ArgumentException"/> if there is any null or empty string in <paramref name="args"/>
        /// </summary>
        /// <param name="args">string array to check</param>
        public static void ThrowIfNullOrEmpty(params string[] args)
        {
            foreach (var item in args)
            {
                if (string.IsNullOrEmpty(item))
                {
                    throw new ArgumentException("must not be null or empty");
                }
            }
        }

        /// <summary>
        /// Throws an <see cref="ArgumentException"/> if there is any null or whitespace string in <paramref name="args"/>
        /// </summary>
        /// <param name="args">string array to check</param>
        public static void ThrowIfNullOrWhiteSpace(params string[] args)
        {
            foreach (var item in args)
            {
                if (string.IsNullOrWhiteSpace(item))
                {
                    throw new ArgumentException("must not be null or whitespace");
                }
            }
        }
    }
}
